package com.suncky.frame.utils;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.suncky.frame.AppConfig;
import com.suncky.frame.utils.activityresult.ActivityResultHelper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;

public class ImagePickHelper {
    private Activity activity;
    private Fragment fragment;
    private String destinationDir;//拍照图片保存路径
    private Uri cameraUri;//拍照图片保存uri
    private boolean crop = false;//是否剪切
    private CallBack callBack;
    private String photoPath;//拍照保存路径
    private Uri corpUri;//裁剪图片保存uri
    private String corpPath;//裁剪图片保存路径
    private String fileProviderAuthority = AppConfig.appContext.getPackageName() + ".provider";//Android N以上版本需要提供的FileProvider authorities名称
    private CropOption cropOption;//剪切参数信息
    private ActivityResultHelper activityResultHelper;

    private static final int REQUEST_CAMERA = 10001;
    private static final int REQUEST_ALBUM = 10002;
    private static final int REQUEST_CORP = 10003;

    private ImagePickHelper() {
    }

    public static ImagePickHelper with(Activity activity) {
        return new ImagePickHelper(activity);
    }

    public static ImagePickHelper with(Fragment fragment) {
        return new ImagePickHelper(fragment);
    }

    private ImagePickHelper(Activity activity) {
        this.activity = activity;
        if (activity instanceof FragmentActivity) {
            activityResultHelper = new ActivityResultHelper((FragmentActivity) activity);
        }
    }

    private ImagePickHelper(Fragment fragment) {
        this.fragment = fragment;
        activityResultHelper = new ActivityResultHelper(fragment);
    }

    /**
     * 是否剪切图片
     * @param crop
     * @return
     */
    public ImagePickHelper crop(boolean crop) {
        this.crop = crop;
        return this;
    }

    /**
     * 拍照图片保存路径，不设置默认保存到系统相册
     * (Android Q及以上只能设置应用沙盒内的路径，否则无法保存照片)
     * @param destinationDir
     * @return
     */
    public ImagePickHelper destinationPath(String destinationDir) {
        this.destinationDir = destinationDir;
        return this;
    }

    /**
     * FileProvider authorities名称,Android N以上版本需要设置,如不设置该属性,默认使用"包名.provider"
     * @param authority
     * @return
     */
    public ImagePickHelper fileProviderAuthority(@NonNull String authority) {
        this.fileProviderAuthority = authority;
        return this;
    }

    /**
     * 设置剪切选项
     * @param cropOption
     * @return
     */
    public ImagePickHelper cropOption(CropOption cropOption) {
        this.cropOption = cropOption;
        return this;
    }


    public ImagePickHelper callBack(CallBack callBack) {
        this.callBack = callBack;
        return this;
    }

    /**
     * 调用系统相机
     */
    public void camera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        String name = System.currentTimeMillis() + ".jpg";
        if (!TextUtils.isEmpty(destinationDir)) {
            FileUtil.createDirectory(destinationDir);
            photoPath = destinationDir + name;
            intent.putExtra(MediaStore.EXTRA_OUTPUT, FileUtil.getUriForFile(getContext(), new File(photoPath),fileProviderAuthority));
        }else {
            photoPath = Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_PICTURES + "/" + name;
            ContentValues values = new ContentValues();
            values.put(MediaStore.MediaColumns.DISPLAY_NAME, name);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
            }else {
                values.put(MediaStore.Images.Media.DATA, photoPath);
            }
            cameraUri= getContext().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
        }
        //启动照相机
        startActivity(intent, REQUEST_CAMERA);
    }

    /**
     * 打开系统相册
     */
    public void album() {
        //调用系统相册
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
        startActivity(intent, REQUEST_ALBUM);
    }

    /**
     * 完成系统相机拍照或者系统相册照片选取之后的数据处理，如传入的是Activity,需要在其onActivityResult中调用此函数，如传入的是FragmentActivity或者Fragment,无需调用此函数
     * @param requestCode
     * @param resultCode
     * @param data
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (activityResultHelper != null) {
            return;
        }
        processActivityResult(requestCode, resultCode, data);
    }

    private void processActivityResult(int requestCode, int resultCode, Intent data) {
        Uri resultUri;
        String resultPath;
        switch (requestCode) {
            case REQUEST_CAMERA://拍照
                if (resultCode != Activity.RESULT_OK) {
                    return;
                }
                if (destinationDir != null || Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
                    resultUri = FileUtil.getUriForFile(getContext(), new File(photoPath), fileProviderAuthority);
                    if (crop) {
                        crop(resultUri);
                        return;
                    }
                    resultPath = photoPath;
                } else {
                    if (cameraUri == null) {
                        return;
                    }
                    if (crop) {
                        crop(cameraUri);
                        return;
                    }
                    try {
                        InputStream is = getContext().getContentResolver().openInputStream(cameraUri);
                        resultPath = AppConfig.imagePath + System.currentTimeMillis() + ".jpg";
                        if (!FileUtil.writeFile(is, resultPath)) {
                            return;
                        }
                        resultUri = FileUtil.getUriForFile(getContext(), new File(resultPath), fileProviderAuthority);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                        return;
                    }
                }
                if (callBack != null) {
                    callBack.onResult(resultUri, resultPath);
                }
                break;
            case REQUEST_ALBUM://选择相册
                if (resultCode != Activity.RESULT_OK || data == null) {
                    return;
                }
                Uri selectedImage = data.getData();
                if (selectedImage == null) {
                    return;
                }
                if (crop) {
                    crop(selectedImage);
                    return;
                }
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    try {
                        InputStream is = getContext().getContentResolver().openInputStream(selectedImage);
                        resultPath = AppConfig.imagePath + System.currentTimeMillis() + getPostfix(selectedImage);
                        if (!FileUtil.writeFile(is, resultPath)) {
                            return;
                        }
                        resultUri = FileUtil.getUriForFile(getContext(), new File(resultPath), fileProviderAuthority);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                        return;
                    }
                } else {
                    String[] filePathColumns = {MediaStore.Images.Media.DATA};
                    Cursor c = getContext().getContentResolver().query(selectedImage, filePathColumns, null, null, null);
                    if (c == null) {
                        return;
                    }
                    c.moveToFirst();
                    resultPath = c.getString(c.getColumnIndex(filePathColumns[0]));
                    c.close();
                    if (resultPath == null) {
                        return;
                    }
                    resultUri = selectedImage;
                }
                if (callBack != null) {
                    callBack.onResult(resultUri, resultPath);
                }
                break;
            case REQUEST_CORP://裁剪图片
                if (resultCode != Activity.RESULT_OK) {
                    return;
                }
                if (callBack != null) {
                    callBack.onResult(corpUri, corpPath);
                }
                break;
        }
    }

    /**
     * 裁剪图片
     * @param uri
     */
    private void crop(Uri uri) {
        if (uri == null) {
            return;
        }
        if (!FileUtil.createDirectory(AppConfig.imagePath)) {
            return;
        }
        if (cropOption == null) {
            cropOption = CropOption.get();
        }
        //裁剪图片保存路径
        corpPath = AppConfig.imagePath + System.currentTimeMillis() + "_corp" + getPostfix(uri);
        corpUri = FileUtil.getUriForFile(getContext(), new File(corpPath),fileProviderAuthority);
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", cropOption.getAspectRatioX());
        intent.putExtra("aspectY", cropOption.getAspectRatioY());
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", cropOption.getOutWidth());
        intent.putExtra("outputY", cropOption.getOutHeight());
        intent.putExtra("return-data", true);
        intent.putExtra("scale", cropOption.isScale());
        intent.putExtra(MediaStore.EXTRA_OUTPUT, corpUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);//取消人脸识别
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            FileUtil.grantPermissions(getContext(),intent, uri,false);
            FileUtil.grantPermissions(getContext(),intent,corpUri,true);
        }
        startActivity(intent,REQUEST_CORP);
    }

    private Context getContext() {
        return fragment != null ? fragment.getContext() : activity;
    }

    private void startActivity(Intent intent, int requestCode) {
        if (activityResultHelper != null) {
            activityResultHelper.startForResult(intent, requestCode, new ActivityResultHelper.ActivityResultCallback() {
                @Override
                public void onActivityResult(int requestCode, int resultCode, Intent data) {
                    processActivityResult(requestCode, resultCode, data);
                }
            });
        } else if (fragment != null) {
            fragment.startActivityForResult(intent, requestCode);
        } else if (activity != null) {
            activity.startActivityForResult(intent, requestCode);
        }
    }

    private String getPostfix(Uri uri) {
        String mimeType = ImageUtils.getMIMEType(getContext(), uri);
        if ("image/png".equals(mimeType)) {
            return ".png";
        }
        return ".jpg";
    }

    public static class CropOption {
        private float mAspectRatioX;
        private float mAspectRatioY;
        private int mOutWidth;
        private int mOutHeight;
        private boolean scale;

        private CropOption() {
            mAspectRatioX = 1;
            mAspectRatioY = 1;
            mOutWidth = 300;
            mOutHeight = 300;
            scale = true;
        }

        public static CropOption get() {
            return new CropOption();
        }

        /**
         * 宽高比
         * @param x
         * @param y
         * @return
         */
        public CropOption aspectRatio(float x, float y) {
            this.mAspectRatioX = x;
            this.mAspectRatioY = y;
            return this;
        }

        /**
         * 使用原始宽高比
         * @return
         */
        public CropOption useSourceImageAspectRatio() {
            this.mAspectRatioX = 0;
            this.mAspectRatioY = 0;
            return this;
        }

        /**
         * 输出图片最大裁剪宽高
         * @param width
         * @param height
         * @return
         */
        public CropOption withMaxResultSize(int width, int height) {
            this.mOutWidth = width;
            this.mOutHeight = height;
            return this;
        }

        /**
         * 是否可缩放
         * @param scale
         * @return
         */
        public CropOption scale(boolean scale) {
            this.scale = scale;
            return this;
        }

        public float getAspectRatioX() {
            return mAspectRatioX;
        }

        public float getAspectRatioY() {
            return mAspectRatioY;
        }

        public int getOutWidth() {
            return mOutWidth;
        }

        public int getOutHeight() {
            return mOutHeight;
        }

        public boolean isScale() {
            return scale;
        }
    }


    public interface CallBack {
        void onResult(Uri uri, String path);
    }
}
